"""
@File    :   validate.py
@Time    :   2024/03/28 19:11:41
@Author  :   Qrj
@Email   :   923207736@qq.com
@description   :   菜单相关验证模型
"""

from datetime import datetime

from pydantic import BaseModel, Field, conint

from src.business.admin.system.menu.enums import MenuTypeEnum
from src.schemas.validate import (
    BaseSearchValidateSchemaMixin,
    BaseValidateSchemaConfigMixin,
)


class MenuCreateValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于创建菜单的验证模型"""

    name: str = Field(default=..., min_length=1, max_length=50, description="菜单名称")
    permission: str = Field(
        default="", min_length=1, max_length=100, description="权限标识"
    )
    type: MenuTypeEnum = Field(
        default=MenuTypeEnum.directory.value, description="菜单类型"
    )
    path: str = Field(
        default="", min_length=1, max_length=200, description="路由地址"
    )  # 外部地址以http(s)://开头
    icon: str = Field(default="", min_length=1, max_length=100, description="菜单图标")
    component: str = Field(
        default="", min_length=1, max_length=255, description="组件路径"
    )
    component_name: str = Field(
        default="", min_length=1, max_length=255, description="组件名称"
    )  # 对应静态路由的name参数
    visible: bool = Field(
        default=True, description="显示状态"
    )  # True显示 False隐藏 (选择隐藏时，路由将不会出现在侧边栏，但仍然可以访问)
    always_show: bool = Field(
        default=True, description="总是显示"
    )  # True是 False否 (选择不是时，当该菜单只有一个子菜单时，不展示自己，直接展示子菜单)
    keep_alive: bool = Field(
        default=True, description="缓存状态"
    )  # True缓存 False不缓存 (选择缓存时，则会被 `keep-alive` 缓存，必须填写「组件名称」字段)
    # 上级菜单ID(删除保护)
    parent_id: int = Field(default=0, description="上级菜单ID")
    status: bool = Field(default=True, description="状态")  # (True正常 False停用)
    remark: str = Field(default="", min_length=1, max_length=300, description="备注")
    show_order: int = Field(default=1, ge=1, le=999999999, description="显示顺序")


class MenuUpdateValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于修改菜单的验证模型"""

    id: int = Field(default=..., ge=1, description="主键")
    name: str = Field(default=..., min_length=1, max_length=50, description="菜单名称")
    permission: str = Field(
        default="", min_length=1, max_length=100, description="权限标识"
    )
    type: MenuTypeEnum = Field(default=MenuTypeEnum.directory, description="菜单类型")
    path: str = Field(
        default="", min_length=1, max_length=200, description="路由地址"
    )  # 外部地址以http(s)://开头
    icon: str = Field(default="", min_length=1, max_length=100, description="菜单图标")
    component: str = Field(
        default="", min_length=1, max_length=255, description="组件路径"
    )
    component_name: str = Field(
        default="", min_length=1, max_length=255, description="组件名称"
    )
    visible: bool = Field(
        default=True, description="显示状态"
    )  # True显示 False隐藏 (选择隐藏时，路由将不会出现在侧边栏，但仍然可以访问)
    always_show: bool = Field(
        default=True, description="总是显示"
    )  # True是 False否 (选择不是时，当该菜单只有一个子菜单时，不展示自己，直接展示子菜单)
    keep_alive: bool = Field(
        default=True, description="缓存状态"
    )  # True缓存 False不缓存 (选择缓存时，则会被 `keep-alive` 缓存，必须填写「组件名称」字段)
    # 上级菜单ID(删除保护)
    parent_id: int = Field(default=0, description="上级菜单ID")
    status: bool = Field(default=True, description="状态")  # (True正常 False停用)
    remark: str = Field(default="", min_length=1, max_length=300, description="备注")
    show_order: int = Field(default=1, ge=1, le=999999999, description="显示顺序")


class MenuUpdateStatusValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于单独修改菜单状态的验证模型"""

    id: int = Field(default=..., ge=1, description="主键")
    status: bool = Field(default=..., description="状态")  # (True正常 False停用)


class MenuDeleteValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于删除菜单的验证模型"""

    ids: list[conint(ge=1)] = Field(
        default=..., min_length=1, description="需删除的主键列表"
    )


class MenuListSearchValidateSchema(BaseModel, BaseSearchValidateSchemaMixin):
    """用于查询菜单列表的验证模型"""

    name: str | None = Field(
        default=None,
        min_length=1,
        max_length=50,
        description="菜单名称",
        json_schema_extra={"str_like_search_type": "complete"},
    )
    type: MenuTypeEnum | None = Field(default=None, description="菜单类型")
    path: str | None = Field(
        default=None,
        min_length=1,
        max_length=200,
        description="路由地址",
        json_schema_extra={"str_like_search_type": "complete"},
    )
    component: str | None = Field(
        default=None,
        min_length=1,
        max_length=255,
        description="组件路径",
        json_schema_extra={"str_like_search_type": "complete"},
    )
    component_name: str | None = Field(
        default=None,
        min_length=1,
        max_length=255,
        description="组件名称",
        json_schema_extra={"str_like_search_type": "complete"},
    )
    visible: bool | None = Field(default=None, description="显示状态")
    always_show: bool | None = Field(default=None, description="总是显示")
    keep_alive: bool | None = Field(default=None, description="缓存状态")
    status: bool = Field(default=True, description="状态")
    remark: str | None = Field(
        default=None,
        min_length=1,
        max_length=300,
        description="备注",
        json_schema_extra={"str_like_search_type": "complete"},
    )
    show_order: int | None = Field(
        default=None, ge=1, le=999999999, description="显示顺序"
    )
    is_system: bool | None = Field(default=None, description="是否系统菜单")
    create_datetime: tuple[datetime, datetime] | None = Field(
        default=None, description="创建时间"
    )
    update_datetime: tuple[datetime, datetime] | None = Field(
        default=None, description="修改时间"
    )
    creator_username: str | None = Field(
        default=None,
        min_length=1,
        max_length=20,
        description="创建者用户名",
        json_schema_extra={"str_like_search_type": "complete"},
    )
    updater_username: str | None = Field(
        default=None,
        min_length=1,
        max_length=20,
        description="修改者用户名",
        json_schema_extra={"str_like_search_type": "complete"},
    )
